std/collections/hash/
set.rs

1#[cfg(test)]
2mod tests;
3
4use hashbrown::hash_set as base;
5
6use super::map::map_try_reserve_error;
7use crate::alloc::{Allocator, Global};
8use crate::borrow::Borrow;
9use crate::collections::TryReserveError;
10use crate::fmt;
11use crate::hash::{BuildHasher, Hash, RandomState};
12use crate::iter::{Chain, FusedIterator};
13use crate::ops::{BitAnd, BitOr, BitXor, Sub};
14
15/// A [hash set] implemented as a `HashMap` where the value is `()`.
16///
17/// As with the [`HashMap`] type, a `HashSet` requires that the elements
18/// implement the [`Eq`] and [`Hash`] traits. This can frequently be achieved by
19/// using `#[derive(PartialEq, Eq, Hash)]`. If you implement these yourself,
20/// it is important that the following property holds:
21///
22/// ```text
23/// k1 == k2 -> hash(k1) == hash(k2)
24/// ```
25///
26/// In other words, if two keys are equal, their hashes must be equal.
27/// Violating this property is a logic error.
28///
29/// It is also a logic error for a key to be modified in such a way that the key's
30/// hash, as determined by the [`Hash`] trait, or its equality, as determined by
31/// the [`Eq`] trait, changes while it is in the map. This is normally only
32/// possible through [`Cell`], [`RefCell`], global state, I/O, or unsafe code.
33///
34/// The behavior resulting from either logic error is not specified, but will
35/// be encapsulated to the `HashSet` that observed the logic error and not
36/// result in undefined behavior. This could include panics, incorrect results,
37/// aborts, memory leaks, and non-termination.
38///
39/// # Examples
40///
41/// ```
42/// use std::collections::HashSet;
43/// // Type inference lets us omit an explicit type signature (which
44/// // would be `HashSet<String>` in this example).
45/// let mut books = HashSet::new();
46///
47/// // Add some books.
48/// books.insert("A Dance With Dragons".to_string());
49/// books.insert("To Kill a Mockingbird".to_string());
50/// books.insert("The Odyssey".to_string());
51/// books.insert("The Great Gatsby".to_string());
52///
53/// // Check for a specific one.
54/// if !books.contains("The Winds of Winter") {
55///     println!("We have {} books, but The Winds of Winter ain't one.",
56///              books.len());
57/// }
58///
59/// // Remove a book.
60/// books.remove("The Odyssey");
61///
62/// // Iterate over everything.
63/// for book in &books {
64///     println!("{book}");
65/// }
66/// ```
67///
68/// The easiest way to use `HashSet` with a custom type is to derive
69/// [`Eq`] and [`Hash`]. We must also derive [`PartialEq`],
70/// which is required if [`Eq`] is derived.
71///
72/// ```
73/// use std::collections::HashSet;
74/// #[derive(Hash, Eq, PartialEq, Debug)]
75/// struct Viking {
76///     name: String,
77///     power: usize,
78/// }
79///
80/// let mut vikings = HashSet::new();
81///
82/// vikings.insert(Viking { name: "Einar".to_string(), power: 9 });
83/// vikings.insert(Viking { name: "Einar".to_string(), power: 9 });
84/// vikings.insert(Viking { name: "Olaf".to_string(), power: 4 });
85/// vikings.insert(Viking { name: "Harald".to_string(), power: 8 });
86///
87/// // Use derived implementation to print the vikings.
88/// for x in &vikings {
89///     println!("{x:?}");
90/// }
91/// ```
92///
93/// A `HashSet` with a known list of items can be initialized from an array:
94///
95/// ```
96/// use std::collections::HashSet;
97///
98/// let viking_names = HashSet::from(["Einar", "Olaf", "Harald"]);
99/// ```
100///
101/// [hash set]: crate::collections#use-the-set-variant-of-any-of-these-maps-when
102/// [`HashMap`]: crate::collections::HashMap
103/// [`RefCell`]: crate::cell::RefCell
104/// [`Cell`]: crate::cell::Cell
105///
106/// # Usage in `const` and `static`
107///
108/// Like `HashMap`, `HashSet` is randomly seeded: each `HashSet` instance uses a different seed,
109/// which means that `HashSet::new` cannot be used in const context. To construct a `HashSet` in the
110/// initializer of a `const` or `static` item, you will have to use a different hasher that does not
111/// involve a random seed, as demonstrated in the following example. **A `HashSet` constructed this
112/// way is not resistant against HashDoS!**
113///
114/// ```rust
115/// use std::collections::HashSet;
116/// use std::hash::{BuildHasherDefault, DefaultHasher};
117/// use std::sync::Mutex;
118///
119/// const EMPTY_SET: HashSet<String, BuildHasherDefault<DefaultHasher>> =
120///     HashSet::with_hasher(BuildHasherDefault::new());
121/// static SET: Mutex<HashSet<String, BuildHasherDefault<DefaultHasher>>> =
122///     Mutex::new(HashSet::with_hasher(BuildHasherDefault::new()));
123/// ```
124#[cfg_attr(not(test), rustc_diagnostic_item = "HashSet")]
125#[stable(feature = "rust1", since = "1.0.0")]
126pub struct HashSet<
127    T,
128    S = RandomState,
129    #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
130> {
131    base: base::HashSet<T, S, A>,
132}
133
134impl<T> HashSet<T, RandomState> {
135    /// Creates an empty `HashSet`.
136    ///
137    /// The hash set is initially created with a capacity of 0, so it will not allocate until it
138    /// is first inserted into.
139    ///
140    /// # Examples
141    ///
142    /// ```
143    /// use std::collections::HashSet;
144    /// let set: HashSet<i32> = HashSet::new();
145    /// ```
146    #[inline]
147    #[must_use]
148    #[stable(feature = "rust1", since = "1.0.0")]
149    pub fn new() -> HashSet<T, RandomState> {
150        Default::default()
151    }
152
153    /// Creates an empty `HashSet` with at least the specified capacity.
154    ///
155    /// The hash set will be able to hold at least `capacity` elements without
156    /// reallocating. This method is allowed to allocate for more elements than
157    /// `capacity`. If `capacity` is zero, the hash set will not allocate.
158    ///
159    /// # Examples
160    ///
161    /// ```
162    /// use std::collections::HashSet;
163    /// let set: HashSet<i32> = HashSet::with_capacity(10);
164    /// assert!(set.capacity() >= 10);
165    /// ```
166    #[inline]
167    #[must_use]
168    #[stable(feature = "rust1", since = "1.0.0")]
169    pub fn with_capacity(capacity: usize) -> HashSet<T, RandomState> {
170        HashSet::with_capacity_and_hasher(capacity, Default::default())
171    }
172}
173
174impl<T, A: Allocator> HashSet<T, RandomState, A> {
175    /// Creates an empty `HashSet` in the provided allocator.
176    ///
177    /// The hash set is initially created with a capacity of 0, so it will not allocate until it
178    /// is first inserted into.
179    #[inline]
180    #[must_use]
181    #[unstable(feature = "allocator_api", issue = "32838")]
182    pub fn new_in(alloc: A) -> HashSet<T, RandomState, A> {
183        HashSet::with_hasher_in(Default::default(), alloc)
184    }
185
186    /// Creates an empty `HashSet` with at least the specified capacity.
187    ///
188    /// The hash set will be able to hold at least `capacity` elements without
189    /// reallocating. This method is allowed to allocate for more elements than
190    /// `capacity`. If `capacity` is zero, the hash set will not allocate.
191    ///
192    /// # Examples
193    ///
194    /// ```
195    /// use std::collections::HashSet;
196    /// let set: HashSet<i32> = HashSet::with_capacity(10);
197    /// assert!(set.capacity() >= 10);
198    /// ```
199    #[inline]
200    #[must_use]
201    #[unstable(feature = "allocator_api", issue = "32838")]
202    pub fn with_capacity_in(capacity: usize, alloc: A) -> HashSet<T, RandomState, A> {
203        HashSet::with_capacity_and_hasher_in(capacity, Default::default(), alloc)
204    }
205}
206
207impl<T, S> HashSet<T, S> {
208    /// Creates a new empty hash set which will use the given hasher to hash
209    /// keys.
210    ///
211    /// The hash set is also created with the default initial capacity.
212    ///
213    /// Warning: `hasher` is normally randomly generated, and
214    /// is designed to allow `HashSet`s to be resistant to attacks that
215    /// cause many collisions and very poor performance. Setting it
216    /// manually using this function can expose a DoS attack vector.
217    ///
218    /// The `hash_builder` passed should implement the [`BuildHasher`] trait for
219    /// the `HashSet` to be useful, see its documentation for details.
220    ///
221    /// # Examples
222    ///
223    /// ```
224    /// use std::collections::HashSet;
225    /// use std::hash::RandomState;
226    ///
227    /// let s = RandomState::new();
228    /// let mut set = HashSet::with_hasher(s);
229    /// set.insert(2);
230    /// ```
231    #[inline]
232    #[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
233    #[rustc_const_stable(feature = "const_collections_with_hasher", since = "1.85.0")]
234    pub const fn with_hasher(hasher: S) -> HashSet<T, S> {
235        HashSet { base: base::HashSet::with_hasher(hasher) }
236    }
237
238    /// Creates an empty `HashSet` with at least the specified capacity, using
239    /// `hasher` to hash the keys.
240    ///
241    /// The hash set will be able to hold at least `capacity` elements without
242    /// reallocating. This method is allowed to allocate for more elements than
243    /// `capacity`. If `capacity` is zero, the hash set will not allocate.
244    ///
245    /// Warning: `hasher` is normally randomly generated, and
246    /// is designed to allow `HashSet`s to be resistant to attacks that
247    /// cause many collisions and very poor performance. Setting it
248    /// manually using this function can expose a DoS attack vector.
249    ///
250    /// The `hash_builder` passed should implement the [`BuildHasher`] trait for
251    /// the `HashSet` to be useful, see its documentation for details.
252    ///
253    /// # Examples
254    ///
255    /// ```
256    /// use std::collections::HashSet;
257    /// use std::hash::RandomState;
258    ///
259    /// let s = RandomState::new();
260    /// let mut set = HashSet::with_capacity_and_hasher(10, s);
261    /// set.insert(1);
262    /// ```
263    #[inline]
264    #[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
265    pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> HashSet<T, S> {
266        HashSet { base: base::HashSet::with_capacity_and_hasher(capacity, hasher) }
267    }
268}
269
270impl<T, S, A: Allocator> HashSet<T, S, A> {
271    /// Creates a new empty hash set which will use the given hasher to hash
272    /// keys and will allocate memory using the provided allocator.
273    ///
274    /// The hash set is also created with the default initial capacity.
275    ///
276    /// Warning: `hasher` is normally randomly generated, and
277    /// is designed to allow `HashSet`s to be resistant to attacks that
278    /// cause many collisions and very poor performance. Setting it
279    /// manually using this function can expose a DoS attack vector.
280    ///
281    /// The `hash_builder` passed should implement the [`BuildHasher`] trait for
282    /// the `HashSet` to be useful, see its documentation for details.
283    #[inline]
284    #[unstable(feature = "allocator_api", issue = "32838")]
285    pub fn with_hasher_in(hasher: S, alloc: A) -> HashSet<T, S, A> {
286        HashSet { base: base::HashSet::with_hasher_in(hasher, alloc) }
287    }
288
289    /// Creates an empty `HashSet` with at least the specified capacity, using
290    /// `hasher` to hash the keys and `alloc` to allocate memory.
291    ///
292    /// The hash set will be able to hold at least `capacity` elements without
293    /// reallocating. This method is allowed to allocate for more elements than
294    /// `capacity`. If `capacity` is zero, the hash set will not allocate.
295    ///
296    /// Warning: `hasher` is normally randomly generated, and
297    /// is designed to allow `HashSet`s to be resistant to attacks that
298    /// cause many collisions and very poor performance. Setting it
299    /// manually using this function can expose a DoS attack vector.
300    ///
301    /// The `hash_builder` passed should implement the [`BuildHasher`] trait for
302    /// the `HashSet` to be useful, see its documentation for details.
303    #[inline]
304    #[unstable(feature = "allocator_api", issue = "32838")]
305    pub fn with_capacity_and_hasher_in(capacity: usize, hasher: S, alloc: A) -> HashSet<T, S, A> {
306        HashSet { base: base::HashSet::with_capacity_and_hasher_in(capacity, hasher, alloc) }
307    }
308
309    /// Returns the number of elements the set can hold without reallocating.
310    ///
311    /// # Examples
312    ///
313    /// ```
314    /// use std::collections::HashSet;
315    /// let set: HashSet<i32> = HashSet::with_capacity(100);
316    /// assert!(set.capacity() >= 100);
317    /// ```
318    #[inline]
319    #[stable(feature = "rust1", since = "1.0.0")]
320    pub fn capacity(&self) -> usize {
321        self.base.capacity()
322    }
323
324    /// An iterator visiting all elements in arbitrary order.
325    /// The iterator element type is `&'a T`.
326    ///
327    /// # Examples
328    ///
329    /// ```
330    /// use std::collections::HashSet;
331    /// let mut set = HashSet::new();
332    /// set.insert("a");
333    /// set.insert("b");
334    ///
335    /// // Will print in an arbitrary order.
336    /// for x in set.iter() {
337    ///     println!("{x}");
338    /// }
339    /// ```
340    ///
341    /// # Performance
342    ///
343    /// In the current implementation, iterating over set takes O(capacity) time
344    /// instead of O(len) because it internally visits empty buckets too.
345    #[inline]
346    #[rustc_lint_query_instability]
347    #[stable(feature = "rust1", since = "1.0.0")]
348    #[cfg_attr(not(test), rustc_diagnostic_item = "hashset_iter")]
349    pub fn iter(&self) -> Iter<'_, T> {
350        Iter { base: self.base.iter() }
351    }
352
353    /// Returns the number of elements in the set.
354    ///
355    /// # Examples
356    ///
357    /// ```
358    /// use std::collections::HashSet;
359    ///
360    /// let mut v = HashSet::new();
361    /// assert_eq!(v.len(), 0);
362    /// v.insert(1);
363    /// assert_eq!(v.len(), 1);
364    /// ```
365    #[inline]
366    #[stable(feature = "rust1", since = "1.0.0")]
367    pub fn len(&self) -> usize {
368        self.base.len()
369    }
370
371    /// Returns `true` if the set contains no elements.
372    ///
373    /// # Examples
374    ///
375    /// ```
376    /// use std::collections::HashSet;
377    ///
378    /// let mut v = HashSet::new();
379    /// assert!(v.is_empty());
380    /// v.insert(1);
381    /// assert!(!v.is_empty());
382    /// ```
383    #[inline]
384    #[stable(feature = "rust1", since = "1.0.0")]
385    pub fn is_empty(&self) -> bool {
386        self.base.is_empty()
387    }
388
389    /// Clears the set, returning all elements as an iterator. Keeps the
390    /// allocated memory for reuse.
391    ///
392    /// If the returned iterator is dropped before being fully consumed, it
393    /// drops the remaining elements. The returned iterator keeps a mutable
394    /// borrow on the set to optimize its implementation.
395    ///
396    /// # Examples
397    ///
398    /// ```
399    /// use std::collections::HashSet;
400    ///
401    /// let mut set = HashSet::from([1, 2, 3]);
402    /// assert!(!set.is_empty());
403    ///
404    /// // print 1, 2, 3 in an arbitrary order
405    /// for i in set.drain() {
406    ///     println!("{i}");
407    /// }
408    ///
409    /// assert!(set.is_empty());
410    /// ```
411    #[inline]
412    #[rustc_lint_query_instability]
413    #[stable(feature = "drain", since = "1.6.0")]
414    pub fn drain(&mut self) -> Drain<'_, T, A> {
415        Drain { base: self.base.drain() }
416    }
417
418    /// Creates an iterator which uses a closure to determine if an element should be removed.
419    ///
420    /// If the closure returns `true`, the element is removed from the set and
421    /// yielded. If the closure returns `false`, or panics, the element remains
422    /// in the set and will not be yielded.
423    ///
424    /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating
425    /// or the iteration short-circuits, then the remaining elements will be retained.
426    /// Use [`retain`] with a negated predicate if you do not need the returned iterator.
427    ///
428    /// [`retain`]: HashSet::retain
429    ///
430    /// # Examples
431    ///
432    /// Splitting a set into even and odd values, reusing the original set:
433    ///
434    /// ```
435    /// use std::collections::HashSet;
436    ///
437    /// let mut set: HashSet<i32> = (0..8).collect();
438    /// let extracted: HashSet<i32> = set.extract_if(|v| v % 2 == 0).collect();
439    ///
440    /// let mut evens = extracted.into_iter().collect::<Vec<_>>();
441    /// let mut odds = set.into_iter().collect::<Vec<_>>();
442    /// evens.sort();
443    /// odds.sort();
444    ///
445    /// assert_eq!(evens, vec![0, 2, 4, 6]);
446    /// assert_eq!(odds, vec![1, 3, 5, 7]);
447    /// ```
448    #[inline]
449    #[rustc_lint_query_instability]
450    #[stable(feature = "hash_extract_if", since = "1.88.0")]
451    pub fn extract_if<F>(&mut self, pred: F) -> ExtractIf<'_, T, F, A>
452    where
453        F: FnMut(&T) -> bool,
454    {
455        ExtractIf { base: self.base.extract_if(pred) }
456    }
457
458    /// Retains only the elements specified by the predicate.
459    ///
460    /// In other words, remove all elements `e` for which `f(&e)` returns `false`.
461    /// The elements are visited in unsorted (and unspecified) order.
462    ///
463    /// # Examples
464    ///
465    /// ```
466    /// use std::collections::HashSet;
467    ///
468    /// let mut set = HashSet::from([1, 2, 3, 4, 5, 6]);
469    /// set.retain(|&k| k % 2 == 0);
470    /// assert_eq!(set, HashSet::from([2, 4, 6]));
471    /// ```
472    ///
473    /// # Performance
474    ///
475    /// In the current implementation, this operation takes O(capacity) time
476    /// instead of O(len) because it internally visits empty buckets too.
477    #[rustc_lint_query_instability]
478    #[stable(feature = "retain_hash_collection", since = "1.18.0")]
479    pub fn retain<F>(&mut self, f: F)
480    where
481        F: FnMut(&T) -> bool,
482    {
483        self.base.retain(f)
484    }
485
486    /// Clears the set, removing all values.
487    ///
488    /// # Examples
489    ///
490    /// ```
491    /// use std::collections::HashSet;
492    ///
493    /// let mut v = HashSet::new();
494    /// v.insert(1);
495    /// v.clear();
496    /// assert!(v.is_empty());
497    /// ```
498    #[inline]
499    #[stable(feature = "rust1", since = "1.0.0")]
500    pub fn clear(&mut self) {
501        self.base.clear()
502    }
503
504    /// Returns a reference to the set's [`BuildHasher`].
505    ///
506    /// # Examples
507    ///
508    /// ```
509    /// use std::collections::HashSet;
510    /// use std::hash::RandomState;
511    ///
512    /// let hasher = RandomState::new();
513    /// let set: HashSet<i32> = HashSet::with_hasher(hasher);
514    /// let hasher: &RandomState = set.hasher();
515    /// ```
516    #[inline]
517    #[stable(feature = "hashmap_public_hasher", since = "1.9.0")]
518    pub fn hasher(&self) -> &S {
519        self.base.hasher()
520    }
521}
522
523impl<T, S, A> HashSet<T, S, A>
524where
525    T: Eq + Hash,
526    S: BuildHasher,
527    A: Allocator,
528{
529    /// Reserves capacity for at least `additional` more elements to be inserted
530    /// in the `HashSet`. The collection may reserve more space to speculatively
531    /// avoid frequent reallocations. After calling `reserve`,
532    /// capacity will be greater than or equal to `self.len() + additional`.
533    /// Does nothing if capacity is already sufficient.
534    ///
535    /// # Panics
536    ///
537    /// Panics if the new allocation size overflows `usize`.
538    ///
539    /// # Examples
540    ///
541    /// ```
542    /// use std::collections::HashSet;
543    /// let mut set: HashSet<i32> = HashSet::new();
544    /// set.reserve(10);
545    /// assert!(set.capacity() >= 10);
546    /// ```
547    #[inline]
548    #[stable(feature = "rust1", since = "1.0.0")]
549    pub fn reserve(&mut self, additional: usize) {
550        self.base.reserve(additional)
551    }
552
553    /// Tries to reserve capacity for at least `additional` more elements to be inserted
554    /// in the `HashSet`. The collection may reserve more space to speculatively
555    /// avoid frequent reallocations. After calling `try_reserve`,
556    /// capacity will be greater than or equal to `self.len() + additional` if
557    /// it returns `Ok(())`.
558    /// Does nothing if capacity is already sufficient.
559    ///
560    /// # Errors
561    ///
562    /// If the capacity overflows, or the allocator reports a failure, then an error
563    /// is returned.
564    ///
565    /// # Examples
566    ///
567    /// ```
568    /// use std::collections::HashSet;
569    /// let mut set: HashSet<i32> = HashSet::new();
570    /// set.try_reserve(10).expect("why is the test harness OOMing on a handful of bytes?");
571    /// ```
572    #[inline]
573    #[stable(feature = "try_reserve", since = "1.57.0")]
574    pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
575        self.base.try_reserve(additional).map_err(map_try_reserve_error)
576    }
577
578    /// Shrinks the capacity of the set as much as possible. It will drop
579    /// down as much as possible while maintaining the internal rules
580    /// and possibly leaving some space in accordance with the resize policy.
581    ///
582    /// # Examples
583    ///
584    /// ```
585    /// use std::collections::HashSet;
586    ///
587    /// let mut set = HashSet::with_capacity(100);
588    /// set.insert(1);
589    /// set.insert(2);
590    /// assert!(set.capacity() >= 100);
591    /// set.shrink_to_fit();
592    /// assert!(set.capacity() >= 2);
593    /// ```
594    #[inline]
595    #[stable(feature = "rust1", since = "1.0.0")]
596    pub fn shrink_to_fit(&mut self) {
597        self.base.shrink_to_fit()
598    }
599
600    /// Shrinks the capacity of the set with a lower limit. It will drop
601    /// down no lower than the supplied limit while maintaining the internal rules
602    /// and possibly leaving some space in accordance with the resize policy.
603    ///
604    /// If the current capacity is less than the lower limit, this is a no-op.
605    /// # Examples
606    ///
607    /// ```
608    /// use std::collections::HashSet;
609    ///
610    /// let mut set = HashSet::with_capacity(100);
611    /// set.insert(1);
612    /// set.insert(2);
613    /// assert!(set.capacity() >= 100);
614    /// set.shrink_to(10);
615    /// assert!(set.capacity() >= 10);
616    /// set.shrink_to(0);
617    /// assert!(set.capacity() >= 2);
618    /// ```
619    #[inline]
620    #[stable(feature = "shrink_to", since = "1.56.0")]
621    pub fn shrink_to(&mut self, min_capacity: usize) {
622        self.base.shrink_to(min_capacity)
623    }
624
625    /// Visits the values representing the difference,
626    /// i.e., the values that are in `self` but not in `other`.
627    ///
628    /// # Examples
629    ///
630    /// ```
631    /// use std::collections::HashSet;
632    /// let a = HashSet::from([1, 2, 3]);
633    /// let b = HashSet::from([4, 2, 3, 4]);
634    ///
635    /// // Can be seen as `a - b`.
636    /// for x in a.difference(&b) {
637    ///     println!("{x}"); // Print 1
638    /// }
639    ///
640    /// let diff: HashSet<_> = a.difference(&b).collect();
641    /// assert_eq!(diff, [1].iter().collect());
642    ///
643    /// // Note that difference is not symmetric,
644    /// // and `b - a` means something else:
645    /// let diff: HashSet<_> = b.difference(&a).collect();
646    /// assert_eq!(diff, [4].iter().collect());
647    /// ```
648    #[inline]
649    #[rustc_lint_query_instability]
650    #[stable(feature = "rust1", since = "1.0.0")]
651    pub fn difference<'a>(&'a self, other: &'a HashSet<T, S, A>) -> Difference<'a, T, S, A> {
652        Difference { iter: self.iter(), other }
653    }
654
655    /// Visits the values representing the symmetric difference,
656    /// i.e., the values that are in `self` or in `other` but not in both.
657    ///
658    /// # Examples
659    ///
660    /// ```
661    /// use std::collections::HashSet;
662    /// let a = HashSet::from([1, 2, 3]);
663    /// let b = HashSet::from([4, 2, 3, 4]);
664    ///
665    /// // Print 1, 4 in arbitrary order.
666    /// for x in a.symmetric_difference(&b) {
667    ///     println!("{x}");
668    /// }
669    ///
670    /// let diff1: HashSet<_> = a.symmetric_difference(&b).collect();
671    /// let diff2: HashSet<_> = b.symmetric_difference(&a).collect();
672    ///
673    /// assert_eq!(diff1, diff2);
674    /// assert_eq!(diff1, [1, 4].iter().collect());
675    /// ```
676    #[inline]
677    #[rustc_lint_query_instability]
678    #[stable(feature = "rust1", since = "1.0.0")]
679    pub fn symmetric_difference<'a>(
680        &'a self,
681        other: &'a HashSet<T, S, A>,
682    ) -> SymmetricDifference<'a, T, S, A> {
683        SymmetricDifference { iter: self.difference(other).chain(other.difference(self)) }
684    }
685
686    /// Visits the values representing the intersection,
687    /// i.e., the values that are both in `self` and `other`.
688    ///
689    /// When an equal element is present in `self` and `other`
690    /// then the resulting `Intersection` may yield references to
691    /// one or the other. This can be relevant if `T` contains fields which
692    /// are not compared by its `Eq` implementation, and may hold different
693    /// value between the two equal copies of `T` in the two sets.
694    ///
695    /// # Examples
696    ///
697    /// ```
698    /// use std::collections::HashSet;
699    /// let a = HashSet::from([1, 2, 3]);
700    /// let b = HashSet::from([4, 2, 3, 4]);
701    ///
702    /// // Print 2, 3 in arbitrary order.
703    /// for x in a.intersection(&b) {
704    ///     println!("{x}");
705    /// }
706    ///
707    /// let intersection: HashSet<_> = a.intersection(&b).collect();
708    /// assert_eq!(intersection, [2, 3].iter().collect());
709    /// ```
710    #[inline]
711    #[rustc_lint_query_instability]
712    #[stable(feature = "rust1", since = "1.0.0")]
713    pub fn intersection<'a>(&'a self, other: &'a HashSet<T, S, A>) -> Intersection<'a, T, S, A> {
714        if self.len() <= other.len() {
715            Intersection { iter: self.iter(), other }
716        } else {
717            Intersection { iter: other.iter(), other: self }
718        }
719    }
720
721    /// Visits the values representing the union,
722    /// i.e., all the values in `self` or `other`, without duplicates.
723    ///
724    /// # Examples
725    ///
726    /// ```
727    /// use std::collections::HashSet;
728    /// let a = HashSet::from([1, 2, 3]);
729    /// let b = HashSet::from([4, 2, 3, 4]);
730    ///
731    /// // Print 1, 2, 3, 4 in arbitrary order.
732    /// for x in a.union(&b) {
733    ///     println!("{x}");
734    /// }
735    ///
736    /// let union: HashSet<_> = a.union(&b).collect();
737    /// assert_eq!(union, [1, 2, 3, 4].iter().collect());
738    /// ```
739    #[inline]
740    #[rustc_lint_query_instability]
741    #[stable(feature = "rust1", since = "1.0.0")]
742    pub fn union<'a>(&'a self, other: &'a HashSet<T, S, A>) -> Union<'a, T, S, A> {
743        if self.len() >= other.len() {
744            Union { iter: self.iter().chain(other.difference(self)) }
745        } else {
746            Union { iter: other.iter().chain(self.difference(other)) }
747        }
748    }
749
750    /// Returns `true` if the set contains a value.
751    ///
752    /// The value may be any borrowed form of the set's value type, but
753    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
754    /// the value type.
755    ///
756    /// # Examples
757    ///
758    /// ```
759    /// use std::collections::HashSet;
760    ///
761    /// let set = HashSet::from([1, 2, 3]);
762    /// assert_eq!(set.contains(&1), true);
763    /// assert_eq!(set.contains(&4), false);
764    /// ```
765    #[inline]
766    #[stable(feature = "rust1", since = "1.0.0")]
767    pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool
768    where
769        T: Borrow<Q>,
770        Q: Hash + Eq,
771    {
772        self.base.contains(value)
773    }
774
775    /// Returns a reference to the value in the set, if any, that is equal to the given value.
776    ///
777    /// The value may be any borrowed form of the set's value type, but
778    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
779    /// the value type.
780    ///
781    /// # Examples
782    ///
783    /// ```
784    /// use std::collections::HashSet;
785    ///
786    /// let set = HashSet::from([1, 2, 3]);
787    /// assert_eq!(set.get(&2), Some(&2));
788    /// assert_eq!(set.get(&4), None);
789    /// ```
790    #[inline]
791    #[stable(feature = "set_recovery", since = "1.9.0")]
792    pub fn get<Q: ?Sized>(&self, value: &Q) -> Option<&T>
793    where
794        T: Borrow<Q>,
795        Q: Hash + Eq,
796    {
797        self.base.get(value)
798    }
799
800    /// Inserts the given `value` into the set if it is not present, then
801    /// returns a reference to the value in the set.
802    ///
803    /// # Examples
804    ///
805    /// ```
806    /// #![feature(hash_set_entry)]
807    ///
808    /// use std::collections::HashSet;
809    ///
810    /// let mut set = HashSet::from([1, 2, 3]);
811    /// assert_eq!(set.len(), 3);
812    /// assert_eq!(set.get_or_insert(2), &2);
813    /// assert_eq!(set.get_or_insert(100), &100);
814    /// assert_eq!(set.len(), 4); // 100 was inserted
815    /// ```
816    #[inline]
817    #[unstable(feature = "hash_set_entry", issue = "60896")]
818    pub fn get_or_insert(&mut self, value: T) -> &T {
819        // Although the raw entry gives us `&mut T`, we only return `&T` to be consistent with
820        // `get`. Key mutation is "raw" because you're not supposed to affect `Eq` or `Hash`.
821        self.base.get_or_insert(value)
822    }
823
824    /// Inserts a value computed from `f` into the set if the given `value` is
825    /// not present, then returns a reference to the value in the set.
826    ///
827    /// # Examples
828    ///
829    /// ```
830    /// #![feature(hash_set_entry)]
831    ///
832    /// use std::collections::HashSet;
833    ///
834    /// let mut set: HashSet<String> = ["cat", "dog", "horse"]
835    ///     .iter().map(|&pet| pet.to_owned()).collect();
836    ///
837    /// assert_eq!(set.len(), 3);
838    /// for &pet in &["cat", "dog", "fish"] {
839    ///     let value = set.get_or_insert_with(pet, str::to_owned);
840    ///     assert_eq!(value, pet);
841    /// }
842    /// assert_eq!(set.len(), 4); // a new "fish" was inserted
843    /// ```
844    #[inline]
845    #[unstable(feature = "hash_set_entry", issue = "60896")]
846    pub fn get_or_insert_with<Q: ?Sized, F>(&mut self, value: &Q, f: F) -> &T
847    where
848        T: Borrow<Q>,
849        Q: Hash + Eq,
850        F: FnOnce(&Q) -> T,
851    {
852        // Although the raw entry gives us `&mut T`, we only return `&T` to be consistent with
853        // `get`. Key mutation is "raw" because you're not supposed to affect `Eq` or `Hash`.
854        self.base.get_or_insert_with(value, f)
855    }
856
857    /// Gets the given value's corresponding entry in the set for in-place manipulation.
858    ///
859    /// # Examples
860    ///
861    /// ```
862    /// #![feature(hash_set_entry)]
863    ///
864    /// use std::collections::HashSet;
865    /// use std::collections::hash_set::Entry::*;
866    ///
867    /// let mut singles = HashSet::new();
868    /// let mut dupes = HashSet::new();
869    ///
870    /// for ch in "a short treatise on fungi".chars() {
871    ///     if let Vacant(dupe_entry) = dupes.entry(ch) {
872    ///         // We haven't already seen a duplicate, so
873    ///         // check if we've at least seen it once.
874    ///         match singles.entry(ch) {
875    ///             Vacant(single_entry) => {
876    ///                 // We found a new character for the first time.
877    ///                 single_entry.insert()
878    ///             }
879    ///             Occupied(single_entry) => {
880    ///                 // We've already seen this once, "move" it to dupes.
881    ///                 single_entry.remove();
882    ///                 dupe_entry.insert();
883    ///             }
884    ///         }
885    ///     }
886    /// }
887    ///
888    /// assert!(!singles.contains(&'t') && dupes.contains(&'t'));
889    /// assert!(singles.contains(&'u') && !dupes.contains(&'u'));
890    /// assert!(!singles.contains(&'v') && !dupes.contains(&'v'));
891    /// ```
892    #[inline]
893    #[unstable(feature = "hash_set_entry", issue = "60896")]
894    pub fn entry(&mut self, value: T) -> Entry<'_, T, S, A> {
895        map_entry(self.base.entry(value))
896    }
897
898    /// Returns `true` if `self` has no elements in common with `other`.
899    /// This is equivalent to checking for an empty intersection.
900    ///
901    /// # Examples
902    ///
903    /// ```
904    /// use std::collections::HashSet;
905    ///
906    /// let a = HashSet::from([1, 2, 3]);
907    /// let mut b = HashSet::new();
908    ///
909    /// assert_eq!(a.is_disjoint(&b), true);
910    /// b.insert(4);
911    /// assert_eq!(a.is_disjoint(&b), true);
912    /// b.insert(1);
913    /// assert_eq!(a.is_disjoint(&b), false);
914    /// ```
915    #[stable(feature = "rust1", since = "1.0.0")]
916    pub fn is_disjoint(&self, other: &HashSet<T, S, A>) -> bool {
917        if self.len() <= other.len() {
918            self.iter().all(|v| !other.contains(v))
919        } else {
920            other.iter().all(|v| !self.contains(v))
921        }
922    }
923
924    /// Returns `true` if the set is a subset of another,
925    /// i.e., `other` contains at least all the values in `self`.
926    ///
927    /// # Examples
928    ///
929    /// ```
930    /// use std::collections::HashSet;
931    ///
932    /// let sup = HashSet::from([1, 2, 3]);
933    /// let mut set = HashSet::new();
934    ///
935    /// assert_eq!(set.is_subset(&sup), true);
936    /// set.insert(2);
937    /// assert_eq!(set.is_subset(&sup), true);
938    /// set.insert(4);
939    /// assert_eq!(set.is_subset(&sup), false);
940    /// ```
941    #[stable(feature = "rust1", since = "1.0.0")]
942    pub fn is_subset(&self, other: &HashSet<T, S, A>) -> bool {
943        if self.len() <= other.len() { self.iter().all(|v| other.contains(v)) } else { false }
944    }
945
946    /// Returns `true` if the set is a superset of another,
947    /// i.e., `self` contains at least all the values in `other`.
948    ///
949    /// # Examples
950    ///
951    /// ```
952    /// use std::collections::HashSet;
953    ///
954    /// let sub = HashSet::from([1, 2]);
955    /// let mut set = HashSet::new();
956    ///
957    /// assert_eq!(set.is_superset(&sub), false);
958    ///
959    /// set.insert(0);
960    /// set.insert(1);
961    /// assert_eq!(set.is_superset(&sub), false);
962    ///
963    /// set.insert(2);
964    /// assert_eq!(set.is_superset(&sub), true);
965    /// ```
966    #[inline]
967    #[stable(feature = "rust1", since = "1.0.0")]
968    pub fn is_superset(&self, other: &HashSet<T, S, A>) -> bool {
969        other.is_subset(self)
970    }
971
972    /// Adds a value to the set.
973    ///
974    /// Returns whether the value was newly inserted. That is:
975    ///
976    /// - If the set did not previously contain this value, `true` is returned.
977    /// - If the set already contained this value, `false` is returned,
978    ///   and the set is not modified: original value is not replaced,
979    ///   and the value passed as argument is dropped.
980    ///
981    /// # Examples
982    ///
983    /// ```
984    /// use std::collections::HashSet;
985    ///
986    /// let mut set = HashSet::new();
987    ///
988    /// assert_eq!(set.insert(2), true);
989    /// assert_eq!(set.insert(2), false);
990    /// assert_eq!(set.len(), 1);
991    /// ```
992    #[inline]
993    #[stable(feature = "rust1", since = "1.0.0")]
994    #[rustc_confusables("push", "append", "put")]
995    pub fn insert(&mut self, value: T) -> bool {
996        self.base.insert(value)
997    }
998
999    /// Adds a value to the set, replacing the existing value, if any, that is equal to the given
1000    /// one. Returns the replaced value.
1001    ///
1002    /// # Examples
1003    ///
1004    /// ```
1005    /// use std::collections::HashSet;
1006    ///
1007    /// let mut set = HashSet::new();
1008    /// set.insert(Vec::<i32>::new());
1009    ///
1010    /// assert_eq!(set.get(&[][..]).unwrap().capacity(), 0);
1011    /// set.replace(Vec::with_capacity(10));
1012    /// assert_eq!(set.get(&[][..]).unwrap().capacity(), 10);
1013    /// ```
1014    #[inline]
1015    #[stable(feature = "set_recovery", since = "1.9.0")]
1016    #[rustc_confusables("swap")]
1017    pub fn replace(&mut self, value: T) -> Option<T> {
1018        self.base.replace(value)
1019    }
1020
1021    /// Removes a value from the set. Returns whether the value was
1022    /// present in the set.
1023    ///
1024    /// The value may be any borrowed form of the set's value type, but
1025    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1026    /// the value type.
1027    ///
1028    /// # Examples
1029    ///
1030    /// ```
1031    /// use std::collections::HashSet;
1032    ///
1033    /// let mut set = HashSet::new();
1034    ///
1035    /// set.insert(2);
1036    /// assert_eq!(set.remove(&2), true);
1037    /// assert_eq!(set.remove(&2), false);
1038    /// ```
1039    #[inline]
1040    #[stable(feature = "rust1", since = "1.0.0")]
1041    #[rustc_confusables("delete", "take")]
1042    pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool
1043    where
1044        T: Borrow<Q>,
1045        Q: Hash + Eq,
1046    {
1047        self.base.remove(value)
1048    }
1049
1050    /// Removes and returns the value in the set, if any, that is equal to the given one.
1051    ///
1052    /// The value may be any borrowed form of the set's value type, but
1053    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1054    /// the value type.
1055    ///
1056    /// # Examples
1057    ///
1058    /// ```
1059    /// use std::collections::HashSet;
1060    ///
1061    /// let mut set = HashSet::from([1, 2, 3]);
1062    /// assert_eq!(set.take(&2), Some(2));
1063    /// assert_eq!(set.take(&2), None);
1064    /// ```
1065    #[inline]
1066    #[stable(feature = "set_recovery", since = "1.9.0")]
1067    pub fn take<Q: ?Sized>(&mut self, value: &Q) -> Option<T>
1068    where
1069        T: Borrow<Q>,
1070        Q: Hash + Eq,
1071    {
1072        self.base.take(value)
1073    }
1074}
1075
1076#[inline]
1077fn map_entry<'a, K: 'a, V: 'a, A: Allocator>(raw: base::Entry<'a, K, V, A>) -> Entry<'a, K, V, A> {
1078    match raw {
1079        base::Entry::Occupied(base) => Entry::Occupied(OccupiedEntry { base }),
1080        base::Entry::Vacant(base) => Entry::Vacant(VacantEntry { base }),
1081    }
1082}
1083
1084#[stable(feature = "rust1", since = "1.0.0")]
1085impl<T, S, A> Clone for HashSet<T, S, A>
1086where
1087    T: Clone,
1088    S: Clone,
1089    A: Allocator + Clone,
1090{
1091    #[inline]
1092    fn clone(&self) -> Self {
1093        Self { base: self.base.clone() }
1094    }
1095
1096    /// Overwrites the contents of `self` with a clone of the contents of `source`.
1097    ///
1098    /// This method is preferred over simply assigning `source.clone()` to `self`,
1099    /// as it avoids reallocation if possible.
1100    #[inline]
1101    fn clone_from(&mut self, other: &Self) {
1102        self.base.clone_from(&other.base);
1103    }
1104}
1105
1106#[stable(feature = "rust1", since = "1.0.0")]
1107impl<T, S, A> PartialEq for HashSet<T, S, A>
1108where
1109    T: Eq + Hash,
1110    S: BuildHasher,
1111    A: Allocator,
1112{
1113    fn eq(&self, other: &HashSet<T, S, A>) -> bool {
1114        if self.len() != other.len() {
1115            return false;
1116        }
1117
1118        self.iter().all(|key| other.contains(key))
1119    }
1120}
1121
1122#[stable(feature = "rust1", since = "1.0.0")]
1123impl<T, S, A> Eq for HashSet<T, S, A>
1124where
1125    T: Eq + Hash,
1126    S: BuildHasher,
1127    A: Allocator,
1128{
1129}
1130
1131#[stable(feature = "rust1", since = "1.0.0")]
1132impl<T, S, A> fmt::Debug for HashSet<T, S, A>
1133where
1134    T: fmt::Debug,
1135    A: Allocator,
1136{
1137    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1138        f.debug_set().entries(self.iter()).finish()
1139    }
1140}
1141
1142#[stable(feature = "rust1", since = "1.0.0")]
1143impl<T, S> FromIterator<T> for HashSet<T, S>
1144where
1145    T: Eq + Hash,
1146    S: BuildHasher + Default,
1147{
1148    #[inline]
1149    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> HashSet<T, S> {
1150        let mut set = HashSet::with_hasher(Default::default());
1151        set.extend(iter);
1152        set
1153    }
1154}
1155
1156#[stable(feature = "std_collections_from_array", since = "1.56.0")]
1157// Note: as what is currently the most convenient built-in way to construct
1158// a HashSet, a simple usage of this function must not *require* the user
1159// to provide a type annotation in order to infer the third type parameter
1160// (the hasher parameter, conventionally "S").
1161// To that end, this impl is defined using RandomState as the concrete
1162// type of S, rather than being generic over `S: BuildHasher + Default`.
1163// It is expected that users who want to specify a hasher will manually use
1164// `with_capacity_and_hasher`.
1165// If type parameter defaults worked on impls, and if type parameter
1166// defaults could be mixed with const generics, then perhaps
1167// this could be generalized.
1168// See also the equivalent impl on HashMap.
1169impl<T, const N: usize> From<[T; N]> for HashSet<T, RandomState>
1170where
1171    T: Eq + Hash,
1172{
1173    /// Converts a `[T; N]` into a `HashSet<T>`.
1174    ///
1175    /// If the array contains any equal values,
1176    /// all but one will be dropped.
1177    ///
1178    /// # Examples
1179    ///
1180    /// ```
1181    /// use std::collections::HashSet;
1182    ///
1183    /// let set1 = HashSet::from([1, 2, 3, 4]);
1184    /// let set2: HashSet<_> = [1, 2, 3, 4].into();
1185    /// assert_eq!(set1, set2);
1186    /// ```
1187    fn from(arr: [T; N]) -> Self {
1188        Self::from_iter(arr)
1189    }
1190}
1191
1192#[stable(feature = "rust1", since = "1.0.0")]
1193impl<T, S, A> Extend<T> for HashSet<T, S, A>
1194where
1195    T: Eq + Hash,
1196    S: BuildHasher,
1197    A: Allocator,
1198{
1199    #[inline]
1200    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
1201        self.base.extend(iter);
1202    }
1203
1204    #[inline]
1205    fn extend_one(&mut self, item: T) {
1206        self.base.insert(item);
1207    }
1208
1209    #[inline]
1210    fn extend_reserve(&mut self, additional: usize) {
1211        self.base.extend_reserve(additional);
1212    }
1213}
1214
1215#[stable(feature = "hash_extend_copy", since = "1.4.0")]
1216impl<'a, T, S, A> Extend<&'a T> for HashSet<T, S, A>
1217where
1218    T: 'a + Eq + Hash + Copy,
1219    S: BuildHasher,
1220    A: Allocator,
1221{
1222    #[inline]
1223    fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
1224        self.extend(iter.into_iter().cloned());
1225    }
1226
1227    #[inline]
1228    fn extend_one(&mut self, &item: &'a T) {
1229        self.base.insert(item);
1230    }
1231
1232    #[inline]
1233    fn extend_reserve(&mut self, additional: usize) {
1234        Extend::<T>::extend_reserve(self, additional)
1235    }
1236}
1237
1238#[stable(feature = "rust1", since = "1.0.0")]
1239#[rustc_const_unstable(feature = "const_default", issue = "143894")]
1240impl<T, S> const Default for HashSet<T, S>
1241where
1242    S: [const] Default,
1243{
1244    /// Creates an empty `HashSet<T, S>` with the `Default` value for the hasher.
1245    #[inline]
1246    fn default() -> HashSet<T, S> {
1247        HashSet { base: base::HashSet::with_hasher(Default::default()) }
1248    }
1249}
1250
1251#[stable(feature = "rust1", since = "1.0.0")]
1252impl<T, S> BitOr<&HashSet<T, S>> for &HashSet<T, S>
1253where
1254    T: Eq + Hash + Clone,
1255    S: BuildHasher + Default,
1256{
1257    type Output = HashSet<T, S>;
1258
1259    /// Returns the union of `self` and `rhs` as a new `HashSet<T, S>`.
1260    ///
1261    /// # Examples
1262    ///
1263    /// ```
1264    /// use std::collections::HashSet;
1265    ///
1266    /// let a = HashSet::from([1, 2, 3]);
1267    /// let b = HashSet::from([3, 4, 5]);
1268    ///
1269    /// let set = &a | &b;
1270    ///
1271    /// let mut i = 0;
1272    /// let expected = [1, 2, 3, 4, 5];
1273    /// for x in &set {
1274    ///     assert!(expected.contains(x));
1275    ///     i += 1;
1276    /// }
1277    /// assert_eq!(i, expected.len());
1278    /// ```
1279    fn bitor(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {
1280        self.union(rhs).cloned().collect()
1281    }
1282}
1283
1284#[stable(feature = "rust1", since = "1.0.0")]
1285impl<T, S> BitAnd<&HashSet<T, S>> for &HashSet<T, S>
1286where
1287    T: Eq + Hash + Clone,
1288    S: BuildHasher + Default,
1289{
1290    type Output = HashSet<T, S>;
1291
1292    /// Returns the intersection of `self` and `rhs` as a new `HashSet<T, S>`.
1293    ///
1294    /// # Examples
1295    ///
1296    /// ```
1297    /// use std::collections::HashSet;
1298    ///
1299    /// let a = HashSet::from([1, 2, 3]);
1300    /// let b = HashSet::from([2, 3, 4]);
1301    ///
1302    /// let set = &a & &b;
1303    ///
1304    /// let mut i = 0;
1305    /// let expected = [2, 3];
1306    /// for x in &set {
1307    ///     assert!(expected.contains(x));
1308    ///     i += 1;
1309    /// }
1310    /// assert_eq!(i, expected.len());
1311    /// ```
1312    fn bitand(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {
1313        self.intersection(rhs).cloned().collect()
1314    }
1315}
1316
1317#[stable(feature = "rust1", since = "1.0.0")]
1318impl<T, S> BitXor<&HashSet<T, S>> for &HashSet<T, S>
1319where
1320    T: Eq + Hash + Clone,
1321    S: BuildHasher + Default,
1322{
1323    type Output = HashSet<T, S>;
1324
1325    /// Returns the symmetric difference of `self` and `rhs` as a new `HashSet<T, S>`.
1326    ///
1327    /// # Examples
1328    ///
1329    /// ```
1330    /// use std::collections::HashSet;
1331    ///
1332    /// let a = HashSet::from([1, 2, 3]);
1333    /// let b = HashSet::from([3, 4, 5]);
1334    ///
1335    /// let set = &a ^ &b;
1336    ///
1337    /// let mut i = 0;
1338    /// let expected = [1, 2, 4, 5];
1339    /// for x in &set {
1340    ///     assert!(expected.contains(x));
1341    ///     i += 1;
1342    /// }
1343    /// assert_eq!(i, expected.len());
1344    /// ```
1345    fn bitxor(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {
1346        self.symmetric_difference(rhs).cloned().collect()
1347    }
1348}
1349
1350#[stable(feature = "rust1", since = "1.0.0")]
1351impl<T, S> Sub<&HashSet<T, S>> for &HashSet<T, S>
1352where
1353    T: Eq + Hash + Clone,
1354    S: BuildHasher + Default,
1355{
1356    type Output = HashSet<T, S>;
1357
1358    /// Returns the difference of `self` and `rhs` as a new `HashSet<T, S>`.
1359    ///
1360    /// # Examples
1361    ///
1362    /// ```
1363    /// use std::collections::HashSet;
1364    ///
1365    /// let a = HashSet::from([1, 2, 3]);
1366    /// let b = HashSet::from([3, 4, 5]);
1367    ///
1368    /// let set = &a - &b;
1369    ///
1370    /// let mut i = 0;
1371    /// let expected = [1, 2];
1372    /// for x in &set {
1373    ///     assert!(expected.contains(x));
1374    ///     i += 1;
1375    /// }
1376    /// assert_eq!(i, expected.len());
1377    /// ```
1378    fn sub(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {
1379        self.difference(rhs).cloned().collect()
1380    }
1381}
1382
1383/// An iterator over the items of a `HashSet`.
1384///
1385/// This `struct` is created by the [`iter`] method on [`HashSet`].
1386/// See its documentation for more.
1387///
1388/// [`iter`]: HashSet::iter
1389///
1390/// # Examples
1391///
1392/// ```
1393/// use std::collections::HashSet;
1394///
1395/// let a = HashSet::from([1, 2, 3]);
1396///
1397/// let mut iter = a.iter();
1398/// ```
1399#[stable(feature = "rust1", since = "1.0.0")]
1400#[cfg_attr(not(test), rustc_diagnostic_item = "hashset_iter_ty")]
1401pub struct Iter<'a, K: 'a> {
1402    base: base::Iter<'a, K>,
1403}
1404
1405#[stable(feature = "default_iters_hash", since = "1.83.0")]
1406impl<K> Default for Iter<'_, K> {
1407    #[inline]
1408    fn default() -> Self {
1409        Iter { base: Default::default() }
1410    }
1411}
1412
1413/// An owning iterator over the items of a `HashSet`.
1414///
1415/// This `struct` is created by the [`into_iter`] method on [`HashSet`]
1416/// (provided by the [`IntoIterator`] trait). See its documentation for more.
1417///
1418/// [`into_iter`]: IntoIterator::into_iter
1419///
1420/// # Examples
1421///
1422/// ```
1423/// use std::collections::HashSet;
1424///
1425/// let a = HashSet::from([1, 2, 3]);
1426///
1427/// let mut iter = a.into_iter();
1428/// ```
1429#[stable(feature = "rust1", since = "1.0.0")]
1430pub struct IntoIter<
1431    K,
1432    #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
1433> {
1434    base: base::IntoIter<K, A>,
1435}
1436
1437#[stable(feature = "default_iters_hash", since = "1.83.0")]
1438impl<K> Default for IntoIter<K> {
1439    #[inline]
1440    fn default() -> Self {
1441        IntoIter { base: Default::default() }
1442    }
1443}
1444
1445/// A draining iterator over the items of a `HashSet`.
1446///
1447/// This `struct` is created by the [`drain`] method on [`HashSet`].
1448/// See its documentation for more.
1449///
1450/// [`drain`]: HashSet::drain
1451///
1452/// # Examples
1453///
1454/// ```
1455/// use std::collections::HashSet;
1456///
1457/// let mut a = HashSet::from([1, 2, 3]);
1458///
1459/// let mut drain = a.drain();
1460/// ```
1461#[stable(feature = "rust1", since = "1.0.0")]
1462#[cfg_attr(not(test), rustc_diagnostic_item = "hashset_drain_ty")]
1463pub struct Drain<
1464    'a,
1465    K: 'a,
1466    #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
1467> {
1468    base: base::Drain<'a, K, A>,
1469}
1470
1471/// A draining, filtering iterator over the items of a `HashSet`.
1472///
1473/// This `struct` is created by the [`extract_if`] method on [`HashSet`].
1474///
1475/// [`extract_if`]: HashSet::extract_if
1476///
1477/// # Examples
1478///
1479/// ```
1480/// use std::collections::HashSet;
1481///
1482/// let mut a = HashSet::from([1, 2, 3]);
1483///
1484/// let mut extract_ifed = a.extract_if(|v| v % 2 == 0);
1485/// ```
1486#[stable(feature = "hash_extract_if", since = "1.88.0")]
1487#[must_use = "iterators are lazy and do nothing unless consumed; \
1488    use `retain` to remove and discard elements"]
1489pub struct ExtractIf<
1490    'a,
1491    K,
1492    F,
1493    #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
1494> {
1495    base: base::ExtractIf<'a, K, F, A>,
1496}
1497
1498/// A lazy iterator producing elements in the intersection of `HashSet`s.
1499///
1500/// This `struct` is created by the [`intersection`] method on [`HashSet`].
1501/// See its documentation for more.
1502///
1503/// [`intersection`]: HashSet::intersection
1504///
1505/// # Examples
1506///
1507/// ```
1508/// use std::collections::HashSet;
1509///
1510/// let a = HashSet::from([1, 2, 3]);
1511/// let b = HashSet::from([4, 2, 3, 4]);
1512///
1513/// let mut intersection = a.intersection(&b);
1514/// ```
1515#[must_use = "this returns the intersection as an iterator, \
1516              without modifying either input set"]
1517#[stable(feature = "rust1", since = "1.0.0")]
1518pub struct Intersection<
1519    'a,
1520    T: 'a,
1521    S: 'a,
1522    #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
1523> {
1524    // iterator of the first set
1525    iter: Iter<'a, T>,
1526    // the second set
1527    other: &'a HashSet<T, S, A>,
1528}
1529
1530/// A lazy iterator producing elements in the difference of `HashSet`s.
1531///
1532/// This `struct` is created by the [`difference`] method on [`HashSet`].
1533/// See its documentation for more.
1534///
1535/// [`difference`]: HashSet::difference
1536///
1537/// # Examples
1538///
1539/// ```
1540/// use std::collections::HashSet;
1541///
1542/// let a = HashSet::from([1, 2, 3]);
1543/// let b = HashSet::from([4, 2, 3, 4]);
1544///
1545/// let mut difference = a.difference(&b);
1546/// ```
1547#[must_use = "this returns the difference as an iterator, \
1548              without modifying either input set"]
1549#[stable(feature = "rust1", since = "1.0.0")]
1550pub struct Difference<
1551    'a,
1552    T: 'a,
1553    S: 'a,
1554    #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
1555> {
1556    // iterator of the first set
1557    iter: Iter<'a, T>,
1558    // the second set
1559    other: &'a HashSet<T, S, A>,
1560}
1561
1562/// A lazy iterator producing elements in the symmetric difference of `HashSet`s.
1563///
1564/// This `struct` is created by the [`symmetric_difference`] method on
1565/// [`HashSet`]. See its documentation for more.
1566///
1567/// [`symmetric_difference`]: HashSet::symmetric_difference
1568///
1569/// # Examples
1570///
1571/// ```
1572/// use std::collections::HashSet;
1573///
1574/// let a = HashSet::from([1, 2, 3]);
1575/// let b = HashSet::from([4, 2, 3, 4]);
1576///
1577/// let mut intersection = a.symmetric_difference(&b);
1578/// ```
1579#[must_use = "this returns the difference as an iterator, \
1580              without modifying either input set"]
1581#[stable(feature = "rust1", since = "1.0.0")]
1582pub struct SymmetricDifference<
1583    'a,
1584    T: 'a,
1585    S: 'a,
1586    #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
1587> {
1588    iter: Chain<Difference<'a, T, S, A>, Difference<'a, T, S, A>>,
1589}
1590
1591/// A lazy iterator producing elements in the union of `HashSet`s.
1592///
1593/// This `struct` is created by the [`union`] method on [`HashSet`].
1594/// See its documentation for more.
1595///
1596/// [`union`]: HashSet::union
1597///
1598/// # Examples
1599///
1600/// ```
1601/// use std::collections::HashSet;
1602///
1603/// let a = HashSet::from([1, 2, 3]);
1604/// let b = HashSet::from([4, 2, 3, 4]);
1605///
1606/// let mut union_iter = a.union(&b);
1607/// ```
1608#[must_use = "this returns the union as an iterator, \
1609              without modifying either input set"]
1610#[stable(feature = "rust1", since = "1.0.0")]
1611pub struct Union<
1612    'a,
1613    T: 'a,
1614    S: 'a,
1615    #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
1616> {
1617    iter: Chain<Iter<'a, T>, Difference<'a, T, S, A>>,
1618}
1619
1620#[stable(feature = "rust1", since = "1.0.0")]
1621impl<'a, T, S, A: Allocator> IntoIterator for &'a HashSet<T, S, A> {
1622    type Item = &'a T;
1623    type IntoIter = Iter<'a, T>;
1624
1625    #[inline]
1626    #[rustc_lint_query_instability]
1627    fn into_iter(self) -> Iter<'a, T> {
1628        self.iter()
1629    }
1630}
1631
1632#[stable(feature = "rust1", since = "1.0.0")]
1633impl<T, S, A: Allocator> IntoIterator for HashSet<T, S, A> {
1634    type Item = T;
1635    type IntoIter = IntoIter<T, A>;
1636
1637    /// Creates a consuming iterator, that is, one that moves each value out
1638    /// of the set in arbitrary order. The set cannot be used after calling
1639    /// this.
1640    ///
1641    /// # Examples
1642    ///
1643    /// ```
1644    /// use std::collections::HashSet;
1645    /// let mut set = HashSet::new();
1646    /// set.insert("a".to_string());
1647    /// set.insert("b".to_string());
1648    ///
1649    /// // Not possible to collect to a Vec<String> with a regular `.iter()`.
1650    /// let v: Vec<String> = set.into_iter().collect();
1651    ///
1652    /// // Will print in an arbitrary order.
1653    /// for x in &v {
1654    ///     println!("{x}");
1655    /// }
1656    /// ```
1657    #[inline]
1658    #[rustc_lint_query_instability]
1659    fn into_iter(self) -> IntoIter<T, A> {
1660        IntoIter { base: self.base.into_iter() }
1661    }
1662}
1663
1664#[stable(feature = "rust1", since = "1.0.0")]
1665impl<K> Clone for Iter<'_, K> {
1666    #[inline]
1667    fn clone(&self) -> Self {
1668        Iter { base: self.base.clone() }
1669    }
1670}
1671#[stable(feature = "rust1", since = "1.0.0")]
1672impl<'a, K> Iterator for Iter<'a, K> {
1673    type Item = &'a K;
1674
1675    #[inline]
1676    fn next(&mut self) -> Option<&'a K> {
1677        self.base.next()
1678    }
1679    #[inline]
1680    fn size_hint(&self) -> (usize, Option<usize>) {
1681        self.base.size_hint()
1682    }
1683    #[inline]
1684    fn count(self) -> usize {
1685        self.base.len()
1686    }
1687    #[inline]
1688    fn fold<B, F>(self, init: B, f: F) -> B
1689    where
1690        Self: Sized,
1691        F: FnMut(B, Self::Item) -> B,
1692    {
1693        self.base.fold(init, f)
1694    }
1695}
1696#[stable(feature = "rust1", since = "1.0.0")]
1697impl<K> ExactSizeIterator for Iter<'_, K> {
1698    #[inline]
1699    fn len(&self) -> usize {
1700        self.base.len()
1701    }
1702}
1703#[stable(feature = "fused", since = "1.26.0")]
1704impl<K> FusedIterator for Iter<'_, K> {}
1705
1706#[stable(feature = "std_debug", since = "1.16.0")]
1707impl<K: fmt::Debug> fmt::Debug for Iter<'_, K> {
1708    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1709        f.debug_list().entries(self.clone()).finish()
1710    }
1711}
1712
1713#[stable(feature = "rust1", since = "1.0.0")]
1714impl<K, A: Allocator> Iterator for IntoIter<K, A> {
1715    type Item = K;
1716
1717    #[inline]
1718    fn next(&mut self) -> Option<K> {
1719        self.base.next()
1720    }
1721    #[inline]
1722    fn size_hint(&self) -> (usize, Option<usize>) {
1723        self.base.size_hint()
1724    }
1725    #[inline]
1726    fn count(self) -> usize {
1727        self.base.len()
1728    }
1729    #[inline]
1730    fn fold<B, F>(self, init: B, f: F) -> B
1731    where
1732        Self: Sized,
1733        F: FnMut(B, Self::Item) -> B,
1734    {
1735        self.base.fold(init, f)
1736    }
1737}
1738#[stable(feature = "rust1", since = "1.0.0")]
1739impl<K, A: Allocator> ExactSizeIterator for IntoIter<K, A> {
1740    #[inline]
1741    fn len(&self) -> usize {
1742        self.base.len()
1743    }
1744}
1745#[stable(feature = "fused", since = "1.26.0")]
1746impl<K, A: Allocator> FusedIterator for IntoIter<K, A> {}
1747
1748#[stable(feature = "std_debug", since = "1.16.0")]
1749impl<K: fmt::Debug, A: Allocator> fmt::Debug for IntoIter<K, A> {
1750    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1751        fmt::Debug::fmt(&self.base, f)
1752    }
1753}
1754
1755#[stable(feature = "rust1", since = "1.0.0")]
1756impl<'a, K, A: Allocator> Iterator for Drain<'a, K, A> {
1757    type Item = K;
1758
1759    #[inline]
1760    fn next(&mut self) -> Option<K> {
1761        self.base.next()
1762    }
1763    #[inline]
1764    fn size_hint(&self) -> (usize, Option<usize>) {
1765        self.base.size_hint()
1766    }
1767    #[inline]
1768    fn fold<B, F>(self, init: B, f: F) -> B
1769    where
1770        Self: Sized,
1771        F: FnMut(B, Self::Item) -> B,
1772    {
1773        self.base.fold(init, f)
1774    }
1775}
1776#[stable(feature = "rust1", since = "1.0.0")]
1777impl<K, A: Allocator> ExactSizeIterator for Drain<'_, K, A> {
1778    #[inline]
1779    fn len(&self) -> usize {
1780        self.base.len()
1781    }
1782}
1783#[stable(feature = "fused", since = "1.26.0")]
1784impl<K, A: Allocator> FusedIterator for Drain<'_, K, A> {}
1785
1786#[stable(feature = "std_debug", since = "1.16.0")]
1787impl<K: fmt::Debug, A: Allocator> fmt::Debug for Drain<'_, K, A> {
1788    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1789        fmt::Debug::fmt(&self.base, f)
1790    }
1791}
1792
1793#[stable(feature = "hash_extract_if", since = "1.88.0")]
1794impl<K, F, A: Allocator> Iterator for ExtractIf<'_, K, F, A>
1795where
1796    F: FnMut(&K) -> bool,
1797{
1798    type Item = K;
1799
1800    #[inline]
1801    fn next(&mut self) -> Option<K> {
1802        self.base.next()
1803    }
1804    #[inline]
1805    fn size_hint(&self) -> (usize, Option<usize>) {
1806        self.base.size_hint()
1807    }
1808}
1809
1810#[stable(feature = "hash_extract_if", since = "1.88.0")]
1811impl<K, F, A: Allocator> FusedIterator for ExtractIf<'_, K, F, A> where F: FnMut(&K) -> bool {}
1812
1813#[stable(feature = "hash_extract_if", since = "1.88.0")]
1814impl<K, F, A: Allocator> fmt::Debug for ExtractIf<'_, K, F, A>
1815where
1816    K: fmt::Debug,
1817{
1818    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1819        f.debug_struct("ExtractIf").finish_non_exhaustive()
1820    }
1821}
1822
1823#[stable(feature = "rust1", since = "1.0.0")]
1824impl<T, S, A: Allocator> Clone for Intersection<'_, T, S, A> {
1825    #[inline]
1826    fn clone(&self) -> Self {
1827        Intersection { iter: self.iter.clone(), ..*self }
1828    }
1829}
1830
1831#[stable(feature = "rust1", since = "1.0.0")]
1832impl<'a, T, S, A> Iterator for Intersection<'a, T, S, A>
1833where
1834    T: Eq + Hash,
1835    S: BuildHasher,
1836    A: Allocator,
1837{
1838    type Item = &'a T;
1839
1840    #[inline]
1841    fn next(&mut self) -> Option<&'a T> {
1842        loop {
1843            let elt = self.iter.next()?;
1844            if self.other.contains(elt) {
1845                return Some(elt);
1846            }
1847        }
1848    }
1849
1850    #[inline]
1851    fn size_hint(&self) -> (usize, Option<usize>) {
1852        let (_, upper) = self.iter.size_hint();
1853        (0, upper)
1854    }
1855
1856    #[inline]
1857    fn fold<B, F>(self, init: B, mut f: F) -> B
1858    where
1859        Self: Sized,
1860        F: FnMut(B, Self::Item) -> B,
1861    {
1862        self.iter.fold(init, |acc, elt| if self.other.contains(elt) { f(acc, elt) } else { acc })
1863    }
1864}
1865
1866#[stable(feature = "std_debug", since = "1.16.0")]
1867impl<T, S, A> fmt::Debug for Intersection<'_, T, S, A>
1868where
1869    T: fmt::Debug + Eq + Hash,
1870    S: BuildHasher,
1871    A: Allocator,
1872{
1873    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1874        f.debug_list().entries(self.clone()).finish()
1875    }
1876}
1877
1878#[stable(feature = "fused", since = "1.26.0")]
1879impl<T, S, A> FusedIterator for Intersection<'_, T, S, A>
1880where
1881    T: Eq + Hash,
1882    S: BuildHasher,
1883    A: Allocator,
1884{
1885}
1886
1887#[stable(feature = "rust1", since = "1.0.0")]
1888impl<T, S, A: Allocator> Clone for Difference<'_, T, S, A> {
1889    #[inline]
1890    fn clone(&self) -> Self {
1891        Difference { iter: self.iter.clone(), ..*self }
1892    }
1893}
1894
1895#[stable(feature = "rust1", since = "1.0.0")]
1896impl<'a, T, S, A> Iterator for Difference<'a, T, S, A>
1897where
1898    T: Eq + Hash,
1899    S: BuildHasher,
1900    A: Allocator,
1901{
1902    type Item = &'a T;
1903
1904    #[inline]
1905    fn next(&mut self) -> Option<&'a T> {
1906        loop {
1907            let elt = self.iter.next()?;
1908            if !self.other.contains(elt) {
1909                return Some(elt);
1910            }
1911        }
1912    }
1913
1914    #[inline]
1915    fn size_hint(&self) -> (usize, Option<usize>) {
1916        let (_, upper) = self.iter.size_hint();
1917        (0, upper)
1918    }
1919
1920    #[inline]
1921    fn fold<B, F>(self, init: B, mut f: F) -> B
1922    where
1923        Self: Sized,
1924        F: FnMut(B, Self::Item) -> B,
1925    {
1926        self.iter.fold(init, |acc, elt| if self.other.contains(elt) { acc } else { f(acc, elt) })
1927    }
1928}
1929
1930#[stable(feature = "fused", since = "1.26.0")]
1931impl<T, S, A> FusedIterator for Difference<'_, T, S, A>
1932where
1933    T: Eq + Hash,
1934    S: BuildHasher,
1935    A: Allocator,
1936{
1937}
1938
1939#[stable(feature = "std_debug", since = "1.16.0")]
1940impl<T, S, A> fmt::Debug for Difference<'_, T, S, A>
1941where
1942    T: fmt::Debug + Eq + Hash,
1943    S: BuildHasher,
1944    A: Allocator,
1945{
1946    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1947        f.debug_list().entries(self.clone()).finish()
1948    }
1949}
1950
1951#[stable(feature = "rust1", since = "1.0.0")]
1952impl<T, S, A: Allocator> Clone for SymmetricDifference<'_, T, S, A> {
1953    #[inline]
1954    fn clone(&self) -> Self {
1955        SymmetricDifference { iter: self.iter.clone() }
1956    }
1957}
1958
1959#[stable(feature = "rust1", since = "1.0.0")]
1960impl<'a, T, S, A> Iterator for SymmetricDifference<'a, T, S, A>
1961where
1962    T: Eq + Hash,
1963    S: BuildHasher,
1964    A: Allocator,
1965{
1966    type Item = &'a T;
1967
1968    #[inline]
1969    fn next(&mut self) -> Option<&'a T> {
1970        self.iter.next()
1971    }
1972    #[inline]
1973    fn size_hint(&self) -> (usize, Option<usize>) {
1974        self.iter.size_hint()
1975    }
1976    #[inline]
1977    fn fold<B, F>(self, init: B, f: F) -> B
1978    where
1979        Self: Sized,
1980        F: FnMut(B, Self::Item) -> B,
1981    {
1982        self.iter.fold(init, f)
1983    }
1984}
1985
1986#[stable(feature = "fused", since = "1.26.0")]
1987impl<T, S, A> FusedIterator for SymmetricDifference<'_, T, S, A>
1988where
1989    T: Eq + Hash,
1990    S: BuildHasher,
1991    A: Allocator,
1992{
1993}
1994
1995#[stable(feature = "std_debug", since = "1.16.0")]
1996impl<T, S, A> fmt::Debug for SymmetricDifference<'_, T, S, A>
1997where
1998    T: fmt::Debug + Eq + Hash,
1999    S: BuildHasher,
2000    A: Allocator,
2001{
2002    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2003        f.debug_list().entries(self.clone()).finish()
2004    }
2005}
2006
2007#[stable(feature = "rust1", since = "1.0.0")]
2008impl<T, S, A: Allocator> Clone for Union<'_, T, S, A> {
2009    #[inline]
2010    fn clone(&self) -> Self {
2011        Union { iter: self.iter.clone() }
2012    }
2013}
2014
2015#[stable(feature = "fused", since = "1.26.0")]
2016impl<T, S, A: Allocator> FusedIterator for Union<'_, T, S, A>
2017where
2018    T: Eq + Hash,
2019    S: BuildHasher,
2020{
2021}
2022
2023#[stable(feature = "std_debug", since = "1.16.0")]
2024impl<T, S, A: Allocator> fmt::Debug for Union<'_, T, S, A>
2025where
2026    T: fmt::Debug + Eq + Hash,
2027    S: BuildHasher,
2028    A: Allocator,
2029{
2030    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2031        f.debug_list().entries(self.clone()).finish()
2032    }
2033}
2034
2035#[stable(feature = "rust1", since = "1.0.0")]
2036impl<'a, T, S, A> Iterator for Union<'a, T, S, A>
2037where
2038    T: Eq + Hash,
2039    S: BuildHasher,
2040    A: Allocator,
2041{
2042    type Item = &'a T;
2043
2044    #[inline]
2045    fn next(&mut self) -> Option<&'a T> {
2046        self.iter.next()
2047    }
2048    #[inline]
2049    fn size_hint(&self) -> (usize, Option<usize>) {
2050        self.iter.size_hint()
2051    }
2052    #[inline]
2053    fn count(self) -> usize {
2054        self.iter.count()
2055    }
2056    #[inline]
2057    fn fold<B, F>(self, init: B, f: F) -> B
2058    where
2059        Self: Sized,
2060        F: FnMut(B, Self::Item) -> B,
2061    {
2062        self.iter.fold(init, f)
2063    }
2064}
2065
2066/// A view into a single entry in a set, which may either be vacant or occupied.
2067///
2068/// This `enum` is constructed from the [`entry`] method on [`HashSet`].
2069///
2070/// [`HashSet`]: struct.HashSet.html
2071/// [`entry`]: struct.HashSet.html#method.entry
2072///
2073/// # Examples
2074///
2075/// ```
2076/// #![feature(hash_set_entry)]
2077///
2078/// use std::collections::hash_set::HashSet;
2079///
2080/// let mut set = HashSet::new();
2081/// set.extend(["a", "b", "c"]);
2082/// assert_eq!(set.len(), 3);
2083///
2084/// // Existing value (insert)
2085/// let entry = set.entry("a");
2086/// let _raw_o = entry.insert();
2087/// assert_eq!(set.len(), 3);
2088/// // Nonexistent value (insert)
2089/// set.entry("d").insert();
2090///
2091/// // Existing value (or_insert)
2092/// set.entry("b").or_insert();
2093/// // Nonexistent value (or_insert)
2094/// set.entry("e").or_insert();
2095///
2096/// println!("Our HashSet: {:?}", set);
2097///
2098/// let mut vec: Vec<_> = set.iter().copied().collect();
2099/// // The `Iter` iterator produces items in arbitrary order, so the
2100/// // items must be sorted to test them against a sorted array.
2101/// vec.sort_unstable();
2102/// assert_eq!(vec, ["a", "b", "c", "d", "e"]);
2103/// ```
2104#[unstable(feature = "hash_set_entry", issue = "60896")]
2105pub enum Entry<
2106    'a,
2107    T,
2108    S,
2109    #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
2110> {
2111    /// An occupied entry.
2112    ///
2113    /// # Examples
2114    ///
2115    /// ```
2116    /// #![feature(hash_set_entry)]
2117    ///
2118    /// use std::collections::hash_set::{Entry, HashSet};
2119    ///
2120    /// let mut set = HashSet::from(["a", "b"]);
2121    ///
2122    /// match set.entry("a") {
2123    ///     Entry::Vacant(_) => unreachable!(),
2124    ///     Entry::Occupied(_) => { }
2125    /// }
2126    /// ```
2127    Occupied(OccupiedEntry<'a, T, S, A>),
2128
2129    /// A vacant entry.
2130    ///
2131    /// # Examples
2132    ///
2133    /// ```
2134    /// #![feature(hash_set_entry)]
2135    ///
2136    /// use std::collections::hash_set::{Entry, HashSet};
2137    ///
2138    /// let mut set = HashSet::new();
2139    ///
2140    /// match set.entry("a") {
2141    ///     Entry::Occupied(_) => unreachable!(),
2142    ///     Entry::Vacant(_) => { }
2143    /// }
2144    /// ```
2145    Vacant(VacantEntry<'a, T, S, A>),
2146}
2147
2148#[unstable(feature = "hash_set_entry", issue = "60896")]
2149impl<T: fmt::Debug, S, A: Allocator> fmt::Debug for Entry<'_, T, S, A> {
2150    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2151        match *self {
2152            Entry::Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(),
2153            Entry::Occupied(ref o) => f.debug_tuple("Entry").field(o).finish(),
2154        }
2155    }
2156}
2157
2158/// A view into an occupied entry in a `HashSet`.
2159/// It is part of the [`Entry`] enum.
2160///
2161/// [`Entry`]: enum.Entry.html
2162///
2163/// # Examples
2164///
2165/// ```
2166/// #![feature(hash_set_entry)]
2167///
2168/// use std::collections::hash_set::{Entry, HashSet};
2169///
2170/// let mut set = HashSet::new();
2171/// set.extend(["a", "b", "c"]);
2172///
2173/// let _entry_o = set.entry("a").insert();
2174/// assert_eq!(set.len(), 3);
2175///
2176/// // Existing key
2177/// match set.entry("a") {
2178///     Entry::Vacant(_) => unreachable!(),
2179///     Entry::Occupied(view) => {
2180///         assert_eq!(view.get(), &"a");
2181///     }
2182/// }
2183///
2184/// assert_eq!(set.len(), 3);
2185///
2186/// // Existing key (take)
2187/// match set.entry("c") {
2188///     Entry::Vacant(_) => unreachable!(),
2189///     Entry::Occupied(view) => {
2190///         assert_eq!(view.remove(), "c");
2191///     }
2192/// }
2193/// assert_eq!(set.get(&"c"), None);
2194/// assert_eq!(set.len(), 2);
2195/// ```
2196#[unstable(feature = "hash_set_entry", issue = "60896")]
2197pub struct OccupiedEntry<
2198    'a,
2199    T,
2200    S,
2201    #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
2202> {
2203    base: base::OccupiedEntry<'a, T, S, A>,
2204}
2205
2206#[unstable(feature = "hash_set_entry", issue = "60896")]
2207impl<T: fmt::Debug, S, A: Allocator> fmt::Debug for OccupiedEntry<'_, T, S, A> {
2208    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2209        f.debug_struct("OccupiedEntry").field("value", self.get()).finish()
2210    }
2211}
2212
2213/// A view into a vacant entry in a `HashSet`.
2214/// It is part of the [`Entry`] enum.
2215///
2216/// [`Entry`]: enum.Entry.html
2217///
2218/// # Examples
2219///
2220/// ```
2221/// #![feature(hash_set_entry)]
2222///
2223/// use std::collections::hash_set::{Entry, HashSet};
2224///
2225/// let mut set = HashSet::<&str>::new();
2226///
2227/// let entry_v = match set.entry("a") {
2228///     Entry::Vacant(view) => view,
2229///     Entry::Occupied(_) => unreachable!(),
2230/// };
2231/// entry_v.insert();
2232/// assert!(set.contains("a") && set.len() == 1);
2233///
2234/// // Nonexistent key (insert)
2235/// match set.entry("b") {
2236///     Entry::Vacant(view) => view.insert(),
2237///     Entry::Occupied(_) => unreachable!(),
2238/// }
2239/// assert!(set.contains("b") && set.len() == 2);
2240/// ```
2241#[unstable(feature = "hash_set_entry", issue = "60896")]
2242pub struct VacantEntry<
2243    'a,
2244    T,
2245    S,
2246    #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
2247> {
2248    base: base::VacantEntry<'a, T, S, A>,
2249}
2250
2251#[unstable(feature = "hash_set_entry", issue = "60896")]
2252impl<T: fmt::Debug, S, A: Allocator> fmt::Debug for VacantEntry<'_, T, S, A> {
2253    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2254        f.debug_tuple("VacantEntry").field(self.get()).finish()
2255    }
2256}
2257
2258impl<'a, T, S, A: Allocator> Entry<'a, T, S, A> {
2259    /// Sets the value of the entry, and returns an OccupiedEntry.
2260    ///
2261    /// # Examples
2262    ///
2263    /// ```
2264    /// #![feature(hash_set_entry)]
2265    ///
2266    /// use std::collections::HashSet;
2267    ///
2268    /// let mut set = HashSet::new();
2269    /// let entry = set.entry("horseyland").insert();
2270    ///
2271    /// assert_eq!(entry.get(), &"horseyland");
2272    /// ```
2273    #[inline]
2274    #[unstable(feature = "hash_set_entry", issue = "60896")]
2275    pub fn insert(self) -> OccupiedEntry<'a, T, S, A>
2276    where
2277        T: Hash,
2278        S: BuildHasher,
2279    {
2280        match self {
2281            Entry::Occupied(entry) => entry,
2282            Entry::Vacant(entry) => entry.insert_entry(),
2283        }
2284    }
2285
2286    /// Ensures a value is in the entry by inserting if it was vacant.
2287    ///
2288    /// # Examples
2289    ///
2290    /// ```
2291    /// #![feature(hash_set_entry)]
2292    ///
2293    /// use std::collections::HashSet;
2294    ///
2295    /// let mut set = HashSet::new();
2296    ///
2297    /// // nonexistent key
2298    /// set.entry("poneyland").or_insert();
2299    /// assert!(set.contains("poneyland"));
2300    ///
2301    /// // existing key
2302    /// set.entry("poneyland").or_insert();
2303    /// assert!(set.contains("poneyland"));
2304    /// assert_eq!(set.len(), 1);
2305    /// ```
2306    #[inline]
2307    #[unstable(feature = "hash_set_entry", issue = "60896")]
2308    pub fn or_insert(self)
2309    where
2310        T: Hash,
2311        S: BuildHasher,
2312    {
2313        if let Entry::Vacant(entry) = self {
2314            entry.insert();
2315        }
2316    }
2317
2318    /// Returns a reference to this entry's value.
2319    ///
2320    /// # Examples
2321    ///
2322    /// ```
2323    /// #![feature(hash_set_entry)]
2324    ///
2325    /// use std::collections::HashSet;
2326    ///
2327    /// let mut set = HashSet::new();
2328    /// set.entry("poneyland").or_insert();
2329    ///
2330    /// // existing key
2331    /// assert_eq!(set.entry("poneyland").get(), &"poneyland");
2332    /// // nonexistent key
2333    /// assert_eq!(set.entry("horseland").get(), &"horseland");
2334    /// ```
2335    #[inline]
2336    #[unstable(feature = "hash_set_entry", issue = "60896")]
2337    pub fn get(&self) -> &T {
2338        match *self {
2339            Entry::Occupied(ref entry) => entry.get(),
2340            Entry::Vacant(ref entry) => entry.get(),
2341        }
2342    }
2343}
2344
2345impl<T, S, A: Allocator> OccupiedEntry<'_, T, S, A> {
2346    /// Gets a reference to the value in the entry.
2347    ///
2348    /// # Examples
2349    ///
2350    /// ```
2351    /// #![feature(hash_set_entry)]
2352    ///
2353    /// use std::collections::hash_set::{Entry, HashSet};
2354    ///
2355    /// let mut set = HashSet::new();
2356    /// set.entry("poneyland").or_insert();
2357    ///
2358    /// match set.entry("poneyland") {
2359    ///     Entry::Vacant(_) => panic!(),
2360    ///     Entry::Occupied(entry) => assert_eq!(entry.get(), &"poneyland"),
2361    /// }
2362    /// ```
2363    #[inline]
2364    #[unstable(feature = "hash_set_entry", issue = "60896")]
2365    pub fn get(&self) -> &T {
2366        self.base.get()
2367    }
2368
2369    /// Takes the value out of the entry, and returns it.
2370    /// Keeps the allocated memory for reuse.
2371    ///
2372    /// # Examples
2373    ///
2374    /// ```
2375    /// #![feature(hash_set_entry)]
2376    ///
2377    /// use std::collections::HashSet;
2378    /// use std::collections::hash_set::Entry;
2379    ///
2380    /// let mut set = HashSet::new();
2381    /// // The set is empty
2382    /// assert!(set.is_empty() && set.capacity() == 0);
2383    ///
2384    /// set.entry("poneyland").or_insert();
2385    /// let capacity_before_remove = set.capacity();
2386    ///
2387    /// if let Entry::Occupied(o) = set.entry("poneyland") {
2388    ///     assert_eq!(o.remove(), "poneyland");
2389    /// }
2390    ///
2391    /// assert_eq!(set.contains("poneyland"), false);
2392    /// // Now set hold none elements but capacity is equal to the old one
2393    /// assert!(set.len() == 0 && set.capacity() == capacity_before_remove);
2394    /// ```
2395    #[inline]
2396    #[unstable(feature = "hash_set_entry", issue = "60896")]
2397    pub fn remove(self) -> T {
2398        self.base.remove()
2399    }
2400}
2401
2402impl<'a, T, S, A: Allocator> VacantEntry<'a, T, S, A> {
2403    /// Gets a reference to the value that would be used when inserting
2404    /// through the `VacantEntry`.
2405    ///
2406    /// # Examples
2407    ///
2408    /// ```
2409    /// #![feature(hash_set_entry)]
2410    ///
2411    /// use std::collections::HashSet;
2412    ///
2413    /// let mut set = HashSet::new();
2414    /// assert_eq!(set.entry("poneyland").get(), &"poneyland");
2415    /// ```
2416    #[inline]
2417    #[unstable(feature = "hash_set_entry", issue = "60896")]
2418    pub fn get(&self) -> &T {
2419        self.base.get()
2420    }
2421
2422    /// Take ownership of the value.
2423    ///
2424    /// # Examples
2425    ///
2426    /// ```
2427    /// #![feature(hash_set_entry)]
2428    ///
2429    /// use std::collections::hash_set::{Entry, HashSet};
2430    ///
2431    /// let mut set = HashSet::new();
2432    ///
2433    /// match set.entry("poneyland") {
2434    ///     Entry::Occupied(_) => panic!(),
2435    ///     Entry::Vacant(v) => assert_eq!(v.into_value(), "poneyland"),
2436    /// }
2437    /// ```
2438    #[inline]
2439    #[unstable(feature = "hash_set_entry", issue = "60896")]
2440    pub fn into_value(self) -> T {
2441        self.base.into_value()
2442    }
2443
2444    /// Sets the value of the entry with the VacantEntry's value.
2445    ///
2446    /// # Examples
2447    ///
2448    /// ```
2449    /// #![feature(hash_set_entry)]
2450    ///
2451    /// use std::collections::HashSet;
2452    /// use std::collections::hash_set::Entry;
2453    ///
2454    /// let mut set = HashSet::new();
2455    ///
2456    /// if let Entry::Vacant(o) = set.entry("poneyland") {
2457    ///     o.insert();
2458    /// }
2459    /// assert!(set.contains("poneyland"));
2460    /// ```
2461    #[inline]
2462    #[unstable(feature = "hash_set_entry", issue = "60896")]
2463    pub fn insert(self)
2464    where
2465        T: Hash,
2466        S: BuildHasher,
2467    {
2468        self.base.insert();
2469    }
2470
2471    #[inline]
2472    fn insert_entry(self) -> OccupiedEntry<'a, T, S, A>
2473    where
2474        T: Hash,
2475        S: BuildHasher,
2476    {
2477        OccupiedEntry { base: self.base.insert() }
2478    }
2479}
2480
2481#[allow(dead_code)]
2482fn assert_covariance() {
2483    fn set<'new>(v: HashSet<&'static str>) -> HashSet<&'new str> {
2484        v
2485    }
2486    fn iter<'a, 'new>(v: Iter<'a, &'static str>) -> Iter<'a, &'new str> {
2487        v
2488    }
2489    fn into_iter<'new>(v: IntoIter<&'static str>) -> IntoIter<&'new str> {
2490        v
2491    }
2492    fn difference<'a, 'new>(
2493        v: Difference<'a, &'static str, RandomState>,
2494    ) -> Difference<'a, &'new str, RandomState> {
2495        v
2496    }
2497    fn symmetric_difference<'a, 'new>(
2498        v: SymmetricDifference<'a, &'static str, RandomState>,
2499    ) -> SymmetricDifference<'a, &'new str, RandomState> {
2500        v
2501    }
2502    fn intersection<'a, 'new>(
2503        v: Intersection<'a, &'static str, RandomState>,
2504    ) -> Intersection<'a, &'new str, RandomState> {
2505        v
2506    }
2507    fn union<'a, 'new>(
2508        v: Union<'a, &'static str, RandomState>,
2509    ) -> Union<'a, &'new str, RandomState> {
2510        v
2511    }
2512    fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> {
2513        d
2514    }
2515}